/**
 * @author WY
 * @since 2023/11
 */

type ClientPos = {
  clientX: number;
  clientY: number;
};
export class MarqueeSelectorTool {
  private static instance: MarqueeSelectorTool;
  private startX: number;
  private startY: number;
  private element: HTMLDivElement;
  activing: boolean;
  private constructor(startPos: ClientPos) {
    this.startX = startPos.clientX;
    this.startY = startPos.clientY;
    this.element = document.createElement('div');
    this.element.style.border = '2px solid #55aaff';
    this.element.style.backgroundColor = 'rgba(75, 160, 255, 0.1)';
    this.element.style.position = 'fixed';
    this.element.style.pointerEvents = 'none';
    this.element.style.zIndex = '999';
    document.body.appendChild(this.element);
    this.activing = true;
  }

  public static getInstance(startPos: ClientPos): MarqueeSelectorTool {
    if (!this.instance) {
      this.instance = new MarqueeSelectorTool(startPos);
    }
    return this.instance;
  }

  public setStart(startPos: ClientPos) {
    this.startX = startPos.clientX;
    this.startY = startPos.clientY;
    this.activing = true;
  }

  public updateSelectArea(curPos: ClientPos) {
    const minX = Math.min(this.startX, curPos.clientX);
    const minY = Math.min(this.startY, curPos.clientY);
    const width = Math.abs(this.startX - curPos.clientX);
    const height = Math.abs(this.startY - curPos.clientY);
    this.element.style.left = minX + 'px';
    this.element.style.top = minY + 'px';
    this.element.style.width = width + 'px';
    this.element.style.height = height + 'px';
  }

  public endSelect() {
    this.element.style.left = -1000 + 'px';
    this.element.style.top = -1000 + 'px';
    this.element.style.width = 0 + 'px';
    this.element.style.height = 0 + 'px';
    this.startX = 0;
    this.startY = 0;
    this.activing = false;
  }
}

export const MarqueeSelector = (startClientPos: ClientPos) => {
  return MarqueeSelectorTool.getInstance(startClientPos);
};
